#include "wds_bullet.h"
#include "wds_enemy_manager.h"
#include "wds_fade_blood.h"
#include "gen_game_state.h"
#include "wds_game.h"
#include "wds_player.h"

#include "dd/dd_man.h"
#include "util/timer.h"
#include "math/facing.h"

WDSBullet::WDSBullet(	float Speed,
						bool Rotate,
						float DamagePower,
						BULLET_TYPES Type
					 ) : 
							m_IsAlive(false),
							m_Speed(Speed),
							m_bRotate(Rotate),
							m_Delay(0),
							m_DamagePower(DamagePower),
							m_DamagePercentage(1.0f),
							m_Howlong(0),
							m_Type(Type),							
							m_IsTypeGauss(false),
							m_Alpha(1.0f),
							m_pIgnoreObj(NULL),
							m_bLeaveAlphaTrail(false)							
{
		
	m_Movement.SetMoveSpeed(m_Speed);	
}



void	WDSBullet::Render(const math::Vec2& Offset,float Scale)
{
	if(m_bLeaveAlphaTrail)
	{
		if(!m_IsAlive && m_Alpha <= 0)
			return;	
	}
	else	
	{
		if(!m_IsAlive)
			return;
	}
	

	if(m_Delay > 0 )
		return;

	if(!m_Sprite.GetImage())
		return;

	const math::Vec2 SCREENPOS = GetPos() - Offset;
	if( SCREENPOS.x < 0.0f - m_Sprite.m_SizeOriginal.y || 
		SCREENPOS.x > 1.0f + m_Sprite.m_SizeOriginal.y || 
		SCREENPOS.y < 0.0f  - m_Sprite.m_SizeOriginal.y ||  
		SCREENPOS.y > 1.0f + m_Sprite.m_SizeOriginal.y)
	{
		m_IsAlive = false;		
	}

	m_Sprite.m_Pos = SCREENPOS;	
	m_Sprite.m_Size.x = m_Sprite.m_SizeOriginal.x;
	m_Sprite.m_Size.y = m_Howlong;
	m_Sprite.m_Size *= Scale;
	m_Sprite.m_Color = ColorfRGBA(1.0f,1.0f,1.0f,m_Alpha);
	

	m_Sprite.m_Rotation = m_Facing.GetAngle();
	m_Sprite.RenderRotated();
	
}
	
void	WDSBullet::RenderDebug(const math::Vec2& Offset,float Scale)
{
	if(!m_IsAlive)
		return;	
    	
	dd::Manager&	DD = dd::Manager::Instance();
	DD.AddCircle2D( GetPos() - Offset, m_Radius*Scale, ColorRGBA(255,0,0) );
	
	
	//for(int i = 0; i < (int)(m_Howlong/0.025f); i++)
	{
	//	DD.AddCircle2D( GetPos() + (Dir * (float)i) - Offset, m_Radius*Scale, ColorRGBA(255,0,0) );		
	}
	
}

void	WDSBullet::Tick(float dt, float SkillBulletSpeed,  const math::Vec2& Offset)
{
	
	if(m_Delay > 0)
	{
		m_Delay -= dt;
		if(m_Delay <= 0)
		{
			// Update Pos and Dir
			//WDSGame* pGame = GENGameState::GetGame()->GetGameWDS();
			//WDSPlayer* pPlayer = pGame->GetPlayer();
			//ReSpawn( pPlayer->GetPos(), WDSBullet::STARTPOS_MIDDLE, pPlayer->GetMousePos() + Offset + m_Variation);
			
		}
		return;	
	}

	if(!m_IsAlive)
	{
		if(m_Type == BULLET_TYPE_NORMAL ||m_Type == BULLET_TYPE_GAUSS)
		{
			
			if(m_Alpha > 0)
			{
				m_Alpha -=  dt;
				if(BULLET_TYPE_NORMAL) 
					m_Alpha -=  (dt * 2.0f);	// two times
			}
			else
				m_Alpha = 0;
		}

		return;
	}

	if(m_Howlong < m_Sprite.m_SizeOriginal.y)
	{
		m_Howlong += (m_Movement.GetSpeed()  * dt * 2.2f);
		if(m_Howlong > m_Sprite.m_SizeOriginal.y)
			m_Howlong = m_Sprite.m_SizeOriginal.y;

		//const float Dist = (GetPos() - m_StartPos).Magnitude();

		//if( m_Howlong * 0.5f > Dist)
		//	m_Howlong = Dist;
	}
	

	m_Movement.Tick(dt * SkillBulletSpeed);

	if(m_bRotate)
	{
		m_Facing.SetTarget(m_Facing.GetAngle() + 45.0f);
		m_Facing.Tick(dt);
		
	}
	
	if(m_Sprite.GetImage())
		m_Sprite.Tick(dt);
	
	if( WDSEnemyManager::Instance().HitTest(this))
	{
		if(m_IsTypeGauss == false)
		{
			m_IsAlive = false;			
		}
	}
	
}


void	WDSBullet::Clear()
{

}

void	WDSBullet::Load(const std::string& Name)
{
	m_Sprite.Create(Name);
	
	m_Radius = m_Sprite.m_SizeOriginal.x * 0.5f;  	
	if(m_Radius == 0)
		m_Radius = 0.025f;
}


void	WDSBullet::ReSpawn(	const math::Vec2& Pos,
							WDSBullet::STARTPOS StartDir, 
							float Degree							
							)
{	
	m_DamagePercentage = 1.0f;
	m_pIgnoreObj = NULL;
	m_Alpha = 1.0f;
	m_StartPos = Pos;
	m_Variation = math::Vec2(0,0);
	m_Howlong = 0;
	//math::Vec2 TempTargetDir = TargetDir;
	//TempTargetDir.y /= GraphicsUtil::W2H;
	//math::Vec2 TempPos = Pos;
	//TempPos.y /= GraphicsUtil::W2H;

	m_Facing.SetCurrent(Degree);
	m_IsAlive = true;
		
	m_Sprite.m_Pos = math::Vec2(-1.0f,-1.0f);
	//m_Dir = TargetDir;
	m_Movement.SetCurrent(Pos);
	m_Movement.SetMoveSpeed(m_Speed);
	m_Movement.SetTarget(Degree);
     
}

void				WDSBullet::SetSpeedVariationScale(float Scale)
{	
	m_Movement.SetMoveSpeed(m_Speed * Scale);
}

std::string			WDSBullet::GetSpriteNameByType(WDSBullet::BULLET_TYPES Type)
{
	switch(Type)
	{
		case WDSBullet::BULLET_TYPE_NORMAL:
			return "bullet_normal";
			//return "bullet_plasma";
		break;

		case WDSBullet::BULLET_TYPE_FIRE:
			return "bullet_fire";

		case WDSBullet::BULLET_TYPE_GAUSS:
			return "bullet_normal";
			//return "bullet_plasma";
		break;
		
		case WDSBullet::BULLET_TYPE_ION:
			return "bullet_ion";
		break; 

		case WDSBullet::BULLET_TYPE_PLASMA:
			return "bullet_plasma";
		break;

		case WDSBullet::BULLET_TYPE_ROCKET:
		case WDSBullet::BULLET_TYPE_HOMINGROCKET:
			return "bullet_rocket";
		break;

		case WDSBullet::BULLET_TYPE_PULSE:
			return "bullet_pulse";
		break;
		
		
		default:
			break;
		
				
			
	}
	return "";
}

void		WDSBullet::Kill()
{ 
	m_IsAlive = false; 
}

float		WDSBullet::GetDamagePower() const
{   	
	return m_DamagePower * m_DamagePercentage;
}

bool		WDSBullet::IsCanRespawn() const
{ 
	if(m_Type == BULLET_TYPE_NORMAL || m_Type == BULLET_TYPE_GAUSS)
	{
		return !m_IsAlive && m_Alpha <= 0; 
	}
	else
	{
		return !m_IsAlive;
	}

}

void	WDSBullet::SetMoveBonus( float BonusScale)
{
	m_Movement.SetMoveSpeed(m_Speed * BonusScale);
}

